/*
 *
 *这个类设计的太差，它的功能只需读取数据，而数据的完整性和解析不应该在考虑的范围之内，但也可以看成是在对串口使用的应用封装
 *
 *
 *现在看以前的代码，这叫写的什么鸟东西，不过自己写的还是要自己维护
 *2013-12-21 by zhou
 *
 */

#ifndef SERIALPORT_H
#define SERIALPORT_H

#include <QObject>
#include <QByteArray>
#include <QTimer>
#include "tools/sleep.h"




#include "posix_qextserialport.h"
#include "tools/constant.h"
#include "model/gsmcommand.h"


#define TIMEOUT(MS) ((MS) * 1000)

enum SerialPortMode{ZIGBEE,GSM,_3G};
/**
 * @brief The SerialPortData struct
 */

struct SerialPortData
{
    char type;
    unsigned char cmd;//命令代号
    QByteArray data;//内容
};

/**
 * @brief The SerialPort class
 * 串口控制类，是对下层的封装
 * 现在只实现两种工作模式
 *
 */


class SerialPort : public QObject
{
    Q_OBJECT
public:
    explicit SerialPort(QObject *parent = 0,const QString &fileName = zigbeeSerialPort,SerialPortMode mode = ZIGBEE);
    ~SerialPort();
    /**
     * @brief sendAcmd 发送一个char的命令
     * @param cmd 命令
     */
    void sendAcmd(unsigned char cmd);
    /**
     * @brief getPortSettings 得到配置项
     * @param mode 工作方式
     * @return 配置项集合
     */
    static PortSettings getPortSettings(SerialPortMode mode);
    /**
     * @brief setBaudRate 设置波特率
     * @param settings 填充的配置项结构体
     * @param baudRate 波特率
     */
    static void setBaudRate(PortSettings& settings,const QString &baudRate);
    /**
     * @brief setDataBits 设置数据位
     * @param settings
     * @param dataBits
     */
    static void setDataBits(PortSettings& settings,const QString &dataBits);
    /**
     * @brief setParity 设置校验位
     * @param settings
     * @param parity
     */
    static void setParity(PortSettings& settings,const QString &parity);
    /**
     * @brief setstopBits 设置停止位
     * @param settings
     * @param stopBits
     */
    static void setstopBits(PortSettings& settings,const QString &stopBits);
    /**
     * @brief setTimeOut 设置超时
     * @param settings
     * @param ms
     */
    static void setTimeOut(PortSettings& settings,const QString& ms);
    /**
     * @brief setFlowType 设置数据流形式
     * @param settings
     * @param flowtype
     */
    static void setFlowType(PortSettings &settings, const QString &flowtype);
    /**
     * @brief reset 重新设置串口的参数
     */
    void reset();
    /**
     * @brief Open 打开串口
     */
    void Open();
    /**
     * @brief close 关闭串口
     */
    void close();
    /**
     * @brief changeCollectTimer 重置检测的定时器
     * @param ms 毫秒
     */
    void changeCollectTimer(int ms);// millisecond
    /**
     * @brief changeWorkMode 改变串口的工作方式
     * @param mode 工作模式
     */
    void changeWorkMode(SerialPortMode mode);
signals:

    /**
     * @brief sig_realTimeInfo 上报实时的信息
     * @param info
     */
    void sig_realTimeInfo(const QString &info);
    void sig_close();
    /**
     * @brief sig_SerialPortDataComed 向外部提供zigbee的数据
     * @param data
     */
    void sig_SerialPortDataComed(const SerialPortData& data);

    /**
     * @brief sig_GSMinfo GSM信息
     * @param message
     */
    void sig_GSMinfo(const QByteArray& message);//
    /**
     * @brief sig_GSMCMDok 报告model的运行状态
     * @param flag
     */
    void sig_GSMCMDok(int flag);//与gsm控制发送什么链接
    /**
     * @brief sig_SerialPortInfo 报告设备名和设备状态
     * @param fileName
     * @param onOff
     */
    void sig_SerialPortInfo(const QString &fileName,bool onOff);

    //gsm猫接受到一条新短信
    void new_gsmMessage(const GSMCommand &cmd_message);




public slots:
    /**
     * @brief wirteCMD 向协调器串口写入控制命令，就是一串字符
     * @param arr 格式为xxxxx xxxx x
     */
    void wirteCMD(const QByteArray &arr);

    /**
     * @brief slt_open 打开串口
     * @param file 文件名
     * @param mode 工作模式
     */
    void slt_open(const QString &file,SerialPortMode mode);
    /**
     * @brief slt_SerialPortInfo
     * @param fileName
     */
    void slt_SerialPortInfo(const QString &fileName);//查看串口设备
    /**
     * @brief slt_setDevOnOrOff
     * @param fileName
     * @param onOff
     */
    void slt_setDevOnOrOff(const QString& fileName,bool onOff);//设置设备的开关
    /**
     * @brief slt_writeSerialPort
     * @param value
     */
    void slt_writeSerialPort(const char *value);
    /**
     * @brief slt_writeSerialPort
     * @param data
     */
    void slt_writeSerialPort(const QByteArray &data);
    /**
     * @brief slt_AT_CMGF
     */
    void slt_AT_CMGF();
    /**
     * @brief slt_AT_CMGS
     * @param len
     */
    void slt_AT_CMGS(int len);
    /**
     * @brief slt_AT_Content
     * @param content
     */
    void slt_AT_Content(const QByteArray &content);


    void slt_close();


    void slt_AT_CNMI();
private slots:
    /**
     * @brief slt_parseSerialPortData
     */
    void slt_parseSerialPortData();
    /**
     * @brief slt_parse 解析buffer中的数据
     */
    void slt_parse();

    //发送错误信息
    void slt_showError();


    void slt_stop_test_timer();
private:
    Posix_QextSerialPort *p_serialPort;
    //  PortSettings m_portsettings;
    quint8 m_currentSize;
    //    QDataStream *p_serialDataStream;
    //  QTimer m_timer;
    bool isRunning;
    QTimer m_test_timer;//测试zigbee网络是使用
    QString m_fileName;
    SerialPortMode workMode;


    /**
     * @brief m_buffer 数据的缓冲区
     */
    QByteArray m_buffer;

    char headFlag;


    quint8 readAquint8();
    void startByGSM();

    QString help_gsm_read(const QString &flag);

    void test_coor();

    GSMCommand parsePhoneGSM(const QString &instr);





};

#endif // SERIALPORT_H
